<template>
    <div class="page-wrap">
        <a-timeline mode="alternate">
            <a-timeline-item
                v-for="(item, index) of days"
                :key="index"
                position="right"
                :color="isWeekday(item.time) ? '#ccc' : '#0176d3'"
                :style="
                    days.length > 15 && index !== 0 && index !== days.length - 2
                        ? {
                              padding: '0 0 5px',
                          }
                        : {}
                "
            >
                <template #dot v-if="item.title || item.showLine">
                    <div style="width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center" :style="{ background: item.color }" v-if="item.title">
                        <CodeOutlined style="font-size: 18px; color: #fff" v-if="item.type === 1" />
                        <UserOutlined style="font-size: 18px; color: #fff" v-if="item.type === 2" />
                        <BellOutlined style="font-size: 18px; color: #fff" v-if="item.type === 3" />
                        <CalendarOutlined style="font-size: 18px; color: #fff" v-if="item.type === 4" />
                        <CarryOutOutlined style="font-size: 18px; color: #fff" v-if="item.type === 5" />
                        <AuditOutlined style="font-size: 18px; color: #fff" v-if="item.type === 6" />

                        <!-- 提前 -->
                        <flexbox style="position: absolute; top: -16px; color: red; right: 50px" v-if="detail[item.riskKey] < 0">
                            <ExclamationCircleFilled style="margin-right: 8px; color: #26a971" />
                            <!-- <a-tag color="green">提前{{ `${Math.ceil(Math.abs(detail[item.riskKey]))}` }}天</a-tag> -->
                            <a-tag color="green">流程提前{{ `${Math.abs(detail[item.riskKey])}` }}天</a-tag>
                        </flexbox>
                        <!-- 延期 -->
                        <flexbox style="position: absolute; top: -16px; color: red; right: 50px" v-if="detail[item.riskKey] > 0">
                            <ExclamationCircleFilled style="margin-right: 8px; color: #fe9339" />
                            <!-- <a-tag color="orange">延期{{ `${Math.ceil(Math.abs(detail[item.riskKey]))}` }}天</a-tag> -->
                            <a-tag color="orange">流程延期{{ `${Math.abs(detail[item.riskKey])}` }}天</a-tag>
                        </flexbox>

                        <div style="position: absolute; top: 13px; left: 36px; width: 270px" :style="{ color: item.lineColor }" v-if="item.showLine">
                            <div>--------------------------------------------</div>
                            <div style="position: absolute; right: 0; top: -10px">{{ item.showLineTitle }} {{ $moment(item.time).format('MM-DD') }}</div>
                        </div>
                    </div>
                    <div style="width: 6px; height: 6px; border-radius: 50%; background: #0176d3" v-else>
                        <div style="position: absolute; left: 6px; top: -1px; width: 284px" :style="{ color: item.lineColor }" v-if="item.showLine">
                            <div>----------------------------------------------</div>
                            <div style="position: absolute; right: 0; top: -10px">{{ item.showLineTitle }} {{ $moment(item.time).format('MM-DD') }}</div>
                        </div>
                    </div>
                </template>
                <template #dot v-else>
                    <div style="width: 6px; height: 6px; border-radius: 50%; background: #0176d3"></div>
                </template>
                <div style="height: 45px; margin-right: 24px" v-if="item.title">
                    <div class="font-w-b">{{ item.time }}</div>
                    <div style="display: flex; align-items: center; justify-content: flex-end">
                        <WarningFilled style="margin-right: 8px; color: #db1c0b" v-if="(item.title.indexOf('测试开始') >= 0 && item.title.indexOf('测试结束') >= 0) || (item.title.indexOf('研发开始') >= 0 && item.title.indexOf('研发结束') >= 0)" />
                        <span>{{ item.title.join(' ') }}</span>
                    </div>
                </div>
                <div style="height: 45px" v-if="index < days.length - 1 ? days[index + 1].title : false" />
                <div style="height: 8px" />
            </a-timeline-item>
        </a-timeline>
    </div>
</template>
<script lang="ts">
import moment from 'moment';
import { ClockCircleOutlined, CodeOutlined, UserOutlined, BellOutlined, ExclamationCircleFilled, CalendarOutlined, CarryOutOutlined, AuditOutlined, WarningFilled } from '@ant-design/icons-vue';
import { defineComponent, reactive, toRefs } from 'vue';
export default defineComponent({
    props: {
        data: {
            type: Object,
            default: () => ({})
        },
        detail: {
            type: Object,
            default: () => ({})
        }
    },
    components: {
        ClockCircleOutlined,
        CodeOutlined,
        UserOutlined,
        BellOutlined,
        ExclamationCircleFilled,
        CalendarOutlined,
        CarryOutOutlined,
        AuditOutlined,
        WarningFilled
    },
    setup(props) {
        const state = reactive<any>({
            days: [],
            planDates: [],
            ranndDates: []
        });

        // {time:'',tag:['研发开始','测试开始'],iconColor:'',isShowLine:'',lineColor:'',riskText:''}

        const isWeekday = (day) => {
            if (moment(day).weekday() === 5 || moment(day).weekday() === 6) {
                return true;
            }
        };
        // 获取点数据
        const getTarget = (date) => {
            const dayPlanObj: any = {
                onlineTimeOffset: {
                    time: props.detail.versionExpectTime ? moment(props.detail.versionExpectTime).format('YYYY-MM-DD') : '',
                    title: '计划上线时间',
                    type: 3,
                    color: '#db1c0b'
                },
                randdStartOffset: {
                    time: props.detail.versionRanddPlanStartTime ? moment(props.detail.versionRanddPlanStartTime).format('YYYY-MM-DD') : '',
                    title: '研发计划开始日期',
                    type: 1,
                    color: '#0176d3'
                },
                randdEndOffset: {
                    time: props.detail.versionRanddPlanEndTime ? moment(props.detail.versionRanddPlanEndTime).format('YYYY-MM-DD') : '',
                    title: '研发计划结束日期',
                    type: 1,
                    color: '#0176d3'
                },
                testStartOffset: {
                    time: props.detail.versionTestPlanStartTime ? moment(props.detail.versionTestPlanStartTime).format('YYYY-MM-DD') : '',
                    title: '测试计划开始时间',
                    type: 2,
                    color: '#26a971'
                },
                testConsumingOffset: {
                    time: props.detail.versionTestPlanEndTime ? moment(props.detail.versionTestPlanEndTime).format('YYYY-MM-DD') : '',
                    title: '测试计划结束时间',
                    type: 2,
                    color: '#26a971'
                }
            };
            const dayRanddList: any = [
                {
                    time: props.detail.businessCreateTime ? moment(props.detail.businessCreateTime).format('YYYY-MM-DD') : '',
                    title: '需求提出',
                    type: 4,
                    color: '#0176d3'
                },
                {
                    time: props.detail.businessAcceptTime ? moment(props.detail.businessAcceptTime).format('YYYY-MM-DD') : '',
                    title: '需求受理',
                    type: 5,
                    color: '#0176d3'
                },
                {
                    time: props.detail.businessSubmitTime ? moment(props.detail.businessSubmitTime).format('YYYY-MM-DD') : '',
                    title: '提交业务方确认时间',
                    type: 6,
                    color: '#0176d3'
                },
                {
                    time: props.detail.businessConfirmTime ? moment(props.detail.businessConfirmTime).format('YYYY-MM-DD') : '',
                    title: '业务方确认时间',
                    type: 6,
                    color: '#0176d3'
                },
                {
                    time: props.detail.versionOnlineRealTime ? moment(props.detail.versionOnlineRealTime).format('YYYY-MM-DD') : '',
                    title: '完成上线',
                    type: 3,
                    riskKey: 'onlineTimeOffset',
                    color: '#26a971'
                },
                {
                    time: props.detail.versionRanddRealStartTime ? moment(props.detail.versionRanddRealStartTime).format('YYYY-MM-DD') : '',
                    title: '研发开始',
                    type: 1,
                    riskKey: 'randdStartOffset',
                    color: '#0176d3'
                },
                {
                    time: props.detail.versionRanddRealEndTime ? moment(props.detail.versionRanddRealEndTime).format('YYYY-MM-DD') : '',
                    title: '研发结束',
                    type: 1,
                    riskKey: 'randdEndOffset',
                    color: '#0176d3'
                },
                {
                    time: props.detail.versionTestRealStartTime ? moment(props.detail.versionTestRealStartTime).format('YYYY-MM-DD') : '',
                    title: '测试开始',
                    type: 2,
                    riskKey: 'testStartOffset',
                    color: '#fe9339'
                },
                {
                    time: props.detail.versionTestRealEndTime ? moment(props.detail.versionTestRealEndTime).format('YYYY-MM-DD') : '',
                    title: '测试结束',
                    type: 2,
                    riskKey: 'testEndOffset',
                    color: '#fe9339'
                }
            ];
            let target: any = null;
            const targetArr = dayRanddList.filter((item) => item.time === date);
            if (targetArr.length) {
                target = {
                    ...targetArr[0],
                    title: targetArr.map((item) => item.title)
                };
            }
            Object.keys(dayPlanObj).forEach((key) => {
                // 是否有风险偏差
                if (props.detail[key]) {
                    // 匹配哪一个风险偏差值
                    if (dayPlanObj[key].time === date) {
                        if (target) {
                            if (target.showLineTitle) {
                                target = {
                                    ...target,
                                    showLine: true,
                                    showLineTitle: target.showLineTitle ? target.showLineTitle + ' ' + dayPlanObj[key].title : dayPlanObj[key].title,
                                    lineColor: '#fe9339',
                                    color: '#fe9339'
                                };
                            } else {
                                target = {
                                    ...target,
                                    showLine: true,
                                    showLineTitle: dayPlanObj[key].title,
                                    lineColor: dayPlanObj[key].color
                                };
                            }
                        } else {
                            target = {
                                showLine: true,
                                showLineTitle: dayPlanObj[key].title,
                                type: dayPlanObj[key].type,
                                lineColor: dayPlanObj[key].color,
                                time: moment(date).format('YYYY-MM-DD')
                            };
                        }
                    }
                }
            });
            return target;
        };
        const enumerateDaysBetweenDates = (startDate, endDate) => {
            let count = 0;
            let index = 1;
            let days: any = [];
            // 假定你已经保证了startDate 小于endDate，且二者不相等
            const SDate = moment(startDate);
            const EDate = moment(endDate);

            let target: any = getTarget(SDate.format('YYYY-MM-DD'));
            if (target) {
                days.push(target);
                count = index;
            } else {
                days.push({
                    time: SDate.format('YYYY-MM-DD')
                });
            }

            while (SDate.add(1, 'days').isBefore(EDate)) {
                index++;
                // 注意这里add方法处理后SDate对象已经改变。
                target = getTarget(SDate.format('YYYY-MM-DD'));
                if (target) {
                    days.push(target);
                    count = index;
                } else {
                    days.push({
                        time: SDate.format('YYYY-MM-DD')
                    });
                }
            }
            index++;
            target = getTarget(EDate.format('YYYY-MM-DD'));
            if (target) {
                days.push(target);
                count = index;
            } else {
                days.push({
                    time: EDate.format('YYYY-MM-DD')
                });
            }
            days = days.slice(0, count).filter((item) => item.title || item.showLine);
            return days;
        };

        const init = () => {
            getDayList();
        };
        const getDayList = () => {
            const { versionExpectTime, versionOnlineRealTime, versionRanddPlanStartTime, versionRanddRealStartTime, versionRanddPlanEndTime, versionRanddRealEndTime, versionTestPlanStartTime, versionTestRealStartTime, versionTestPlanEndTime, versionTestRealEndTime, businessCreateTime, businessAcceptTime, businessSubmitTime, businessConfirmTime } = props.detail;
            const dates = [versionExpectTime, versionOnlineRealTime, versionRanddPlanStartTime, versionRanddRealStartTime, versionRanddPlanEndTime, versionRanddRealEndTime, versionTestPlanStartTime, versionTestRealStartTime, versionTestPlanEndTime, versionTestRealEndTime, businessCreateTime, businessAcceptTime, businessSubmitTime, businessConfirmTime];
            const res = dates.some((item) => item);
            if (res) {
                let min = moment(dates[0]);
                let max = moment(dates[0]);
                for (let i = 0; i < dates.length; i++) {
                    const element = dates[i];
                    if (!element) {
                        continue;
                    }
                    const start = moment(element);
                    const end = moment(element);

                    if (start < min) {
                        min = start;
                    }

                    if (end > max) {
                        max = end;
                    }
                }
                state.days = enumerateDaysBetweenDates(min.format('YYYY-MM-DD'), max.format('YYYY-MM-DD'));
            }
        };
        init();
        return {
            ...toRefs(state),
            isWeekday
        };
    }
});
</script>
<style scoped lang="less">
.page-wrap {
    background: #fff;
    padding: 24px;
    margin-top: 12px;
}
</style>

